<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title>Coverage for c:\program files\python26\lib\site-packages\modbus_tk-0.3-py2.6.egg\modbus_tk\modbus_tcp</title>
<link rel='stylesheet' href='style.css' type='text/css'>
<script type='text/javascript' src='jquery-1.3.2.min.js'></script>
<script type='text/javascript'>
function toggle_lines(btn, cls) {
    var btn = $(btn);
    var hide = "hide_"+cls;
    if (btn.hasClass(hide)) {
        $("#source ."+cls).removeClass(hide);
        btn.removeClass(hide);
    }
    else {
        $("#source ."+cls).addClass(hide);
        btn.addClass(hide);
    }
}
</script>
</head>
<body>
<div id='header'>
    <div class='content'>
        <h1>Coverage for <b>c:\program files\python26\lib\site-packages\modbus_tk-0.3-py2.6.egg\modbus_tk\modbus_tcp</b> :
            <span class='pc_cov'>81%</span>
        </h1>
        <h2 class='stats'>
            213 statements
            <span class='run hide_run' onclick='toggle_lines(this, "run")'>182 run</span>
            <span class='exc' onclick='toggle_lines(this, "exc")'>0 excluded</span>
            <span class='mis' onclick='toggle_lines(this, "mis")'>31 missing</span>
            
                <span class='par run hide_run' onclick='toggle_lines(this, "par")'>23 partial</span>
            
        </h2>
    </div>
</div>

<div id='source'>
<table cellspacing='0' cellpadding='0'>
<tr>
<td class='linenos' valign='top'>
<p class='pln'>1</p>
<p class='pln'>2</p>
<p class='stm run hide_run'>3</p>
<p class='pln'>4</p>
<p class='pln'>5</p>
<p class='pln'>6</p>
<p class='pln'>7</p>
<p class='pln'>8</p>
<p class='pln'>9</p>
<p class='pln'>10</p>
<p class='pln'>11</p>
<p class='stm run hide_run'>12</p>
<p class='stm run hide_run'>13</p>
<p class='stm run hide_run'>14</p>
<p class='stm run hide_run'>15</p>
<p class='stm run hide_run'>16</p>
<p class='stm run hide_run'>17</p>
<p class='stm run hide_run'>18</p>
<p class='pln'>19</p>
<p class='pln'>20</p>
<p class='stm run hide_run'>21</p>
<p class='pln'>22</p>
<p class='stm run hide_run'>23</p>
<p class='stm mis'>24</p>
<p class='pln'>25</p>
<p class='pln'>26</p>
<p class='stm run hide_run'>27</p>
<p class='pln'>28</p>
<p class='stm run hide_run'>29</p>
<p class='pln'>30</p>
<p class='stm run hide_run'>31</p>
<p class='stm run hide_run'>32</p>
<p class='stm run hide_run'>33</p>
<p class='stm run hide_run'>34</p>
<p class='pln'>35</p>
<p class='stm run hide_run'>36</p>
<p class='pln'>37</p>
<p class='stm run hide_run'>38</p>
<p class='stm run hide_run'>39</p>
<p class='stm run hide_run'>40</p>
<p class='stm run hide_run'>41</p>
<p class='pln'>42</p>
<p class='stm run hide_run'>43</p>
<p class='pln'>44</p>
<p class='pln'>45</p>
<p class='pln'>46</p>
<p class='pln'>47</p>
<p class='stm run hide_run'>48</p>
<p class='pln'>49</p>
<p class='stm par run hide_run'>50</p>
<p class='stm mis'>51</p>
<p class='pln'>52</p>
<p class='pln'>53</p>
<p class='stm par run hide_run'>54</p>
<p class='stm mis'>55</p>
<p class='pln'>56</p>
<p class='pln'>57</p>
<p class='stm par run hide_run'>58</p>
<p class='stm mis'>59</p>
<p class='pln'>60</p>
<p class='stm run hide_run'>61</p>
<p class='pln'>62</p>
<p class='stm run hide_run'>63</p>
<p class='pln'>64</p>
<p class='stm run hide_run'>65</p>
<p class='stm par run hide_run'>66</p>
<p class='stm mis'>67</p>
<p class='stm run hide_run'>68</p>
<p class='pln'>69</p>
<p class='stm run hide_run'>70</p>
<p class='pln'>71</p>
<p class='stm run hide_run'>72</p>
<p class='stm run hide_run'>73</p>
<p class='stm par run hide_run'>74</p>
<p class='stm mis'>75</p>
<p class='pln'>76</p>
<p class='stm run hide_run'>77</p>
<p class='pln'>78</p>
<p class='stm run hide_run'>79</p>
<p class='pln'>80</p>
<p class='stm run hide_run'>81</p>
<p class='pln'>82</p>
<p class='stm run hide_run'>83</p>
<p class='pln'>84</p>
<p class='pln'>85</p>
<p class='stm run hide_run'>86</p>
<p class='pln'>87</p>
<p class='pln'>88</p>
<p class='pln'>89</p>
<p class='stm run hide_run'>90</p>
<p class='pln'>91</p>
<p class='stm run hide_run'>92</p>
<p class='pln'>93</p>
<p class='stm run hide_run'>94</p>
<p class='stm run hide_run'>95</p>
<p class='stm run hide_run'>96</p>
<p class='pln'>97</p>
<p class='stm run hide_run'>98</p>
<p class='pln'>99</p>
<p class='pln'>100</p>
<p class='stm par run hide_run'>101</p>
<p class='stm run hide_run'>102</p>
<p class='pln'>103</p>
<p class='stm mis'>104</p>
<p class='stm run hide_run'>105</p>
<p class='pln'>106</p>
<p class='stm run hide_run'>107</p>
<p class='pln'>108</p>
<p class='stm par run hide_run'>109</p>
<p class='stm mis'>110</p>
<p class='stm run hide_run'>111</p>
<p class='stm run hide_run'>112</p>
<p class='stm run hide_run'>113</p>
<p class='stm run hide_run'>114</p>
<p class='stm run hide_run'>115</p>
<p class='pln'>116</p>
<p class='stm run hide_run'>117</p>
<p class='pln'>118</p>
<p class='stm par run hide_run'>119</p>
<p class='stm run hide_run'>120</p>
<p class='stm run hide_run'>121</p>
<p class='stm run hide_run'>122</p>
<p class='stm run hide_run'>123</p>
<p class='pln'>124</p>
<p class='stm mis'>125</p>
<p class='pln'>126</p>
<p class='stm run hide_run'>127</p>
<p class='pln'>128</p>
<p class='stm par run hide_run'>129</p>
<p class='stm run hide_run'>130</p>
<p class='stm run hide_run'>131</p>
<p class='stm run hide_run'>132</p>
<p class='stm par run hide_run'>133</p>
<p class='stm mis'>134</p>
<p class='stm run hide_run'>135</p>
<p class='pln'>136</p>
<p class='stm mis'>137</p>
<p class='pln'>138</p>
<p class='stm run hide_run'>139</p>
<p class='pln'>140</p>
<p class='stm run hide_run'>141</p>
<p class='stm run hide_run'>142</p>
<p class='stm run hide_run'>143</p>
<p class='pln'>144</p>
<p class='pln'>145</p>
<p class='stm run hide_run'>146</p>
<p class='pln'>147</p>
<p class='pln'>148</p>
<p class='stm run hide_run'>149</p>
<p class='pln'>150</p>
<p class='stm run hide_run'>151</p>
<p class='stm run hide_run'>152</p>
<p class='stm run hide_run'>153</p>
<p class='stm run hide_run'>154</p>
<p class='pln'>155</p>
<p class='stm run hide_run'>156</p>
<p class='pln'>157</p>
<p class='stm run hide_run'>158</p>
<p class='stm run hide_run'>159</p>
<p class='stm run hide_run'>160</p>
<p class='stm run hide_run'>161</p>
<p class='stm run hide_run'>162</p>
<p class='pln'>163</p>
<p class='stm run hide_run'>164</p>
<p class='pln'>165</p>
<p class='stm par run hide_run'>166</p>
<p class='stm run hide_run'>167</p>
<p class='stm run hide_run'>168</p>
<p class='stm run hide_run'>169</p>
<p class='pln'>170</p>
<p class='stm run hide_run'>171</p>
<p class='pln'>172</p>
<p class='stm run hide_run'>173</p>
<p class='stm run hide_run'>174</p>
<p class='stm run hide_run'>175</p>
<p class='stm par run hide_run'>176</p>
<p class='stm run hide_run'>177</p>
<p class='pln'>178</p>
<p class='stm run hide_run'>179</p>
<p class='pln'>180</p>
<p class='stm run hide_run'>181</p>
<p class='stm par run hide_run'>182</p>
<p class='stm mis'>183</p>
<p class='stm run hide_run'>184</p>
<p class='stm run hide_run'>185</p>
<p class='pln'>186</p>
<p class='stm run hide_run'>187</p>
<p class='pln'>188</p>
<p class='pln'>189</p>
<p class='pln'>190</p>
<p class='pln'>191</p>
<p class='pln'>192</p>
<p class='pln'>193</p>
<p class='stm run hide_run'>194</p>
<p class='stm run hide_run'>195</p>
<p class='stm run hide_run'>196</p>
<p class='stm run hide_run'>197</p>
<p class='stm par run hide_run'>198</p>
<p class='stm run hide_run'>199</p>
<p class='stm run hide_run'>200</p>
<p class='stm run hide_run'>201</p>
<p class='stm run hide_run'>202</p>
<p class='pln'>203</p>
<p class='stm mis'>204</p>
<p class='stm run hide_run'>205</p>
<p class='stm par run hide_run'>206</p>
<p class='stm mis'>207</p>
<p class='stm run hide_run'>208</p>
<p class='pln'>209</p>
<p class='stm run hide_run'>210</p>
<p class='pln'>211</p>
<p class='stm run hide_run'>212</p>
<p class='pln'>213</p>
<p class='pln'>214</p>
<p class='stm run hide_run'>215</p>
<p class='pln'>216</p>
<p class='pln'>217</p>
<p class='stm run hide_run'>218</p>
<p class='pln'>219</p>
<p class='stm run hide_run'>220</p>
<p class='stm run hide_run'>221</p>
<p class='stm run hide_run'>222</p>
<p class='stm run hide_run'>223</p>
<p class='stm run hide_run'>224</p>
<p class='pln'>225</p>
<p class='stm run hide_run'>226</p>
<p class='pln'>227</p>
<p class='stm run hide_run'>228</p>
<p class='pln'>229</p>
<p class='stm run hide_run'>230</p>
<p class='pln'>231</p>
<p class='stm par run hide_run'>232</p>
<p class='stm mis'>233</p>
<p class='stm run hide_run'>234</p>
<p class='stm run hide_run'>235</p>
<p class='pln'>236</p>
<p class='stm run hide_run'>237</p>
<p class='pln'>238</p>
<p class='stm run hide_run'>239</p>
<p class='stm par run hide_run'>240</p>
<p class='stm run hide_run'>241</p>
<p class='stm run hide_run'>242</p>
<p class='stm run hide_run'>243</p>
<p class='stm run hide_run'>244</p>
<p class='stm run hide_run'>245</p>
<p class='pln'>246</p>
<p class='stm run hide_run'>247</p>
<p class='pln'>248</p>
<p class='pln'>249</p>
<p class='stm run hide_run'>250</p>
<p class='stm run hide_run'>251</p>
<p class='stm run hide_run'>252</p>
<p class='stm run hide_run'>253</p>
<p class='stm mis'>254</p>
<p class='stm mis'>255</p>
<p class='pln'>256</p>
<p class='stm run hide_run'>257</p>
<p class='pln'>258</p>
<p class='pln'>259</p>
<p class='stm run hide_run'>260</p>
<p class='pln'>261</p>
<p class='stm run hide_run'>262</p>
<p class='stm run hide_run'>263</p>
<p class='stm run hide_run'>264</p>
<p class='pln'>265</p>
<p class='stm run hide_run'>266</p>
<p class='stm run hide_run'>267</p>
<p class='stm run hide_run'>268</p>
<p class='stm run hide_run'>269</p>
<p class='stm run hide_run'>270</p>
<p class='pln'>271</p>
<p class='stm run hide_run'>272</p>
<p class='pln'>273</p>
<p class='stm run hide_run'>274</p>
<p class='stm run hide_run'>275</p>
<p class='stm run hide_run'>276</p>
<p class='stm run hide_run'>277</p>
<p class='stm run hide_run'>278</p>
<p class='pln'>279</p>
<p class='pln'>280</p>
<p class='stm run hide_run'>281</p>
<p class='stm run hide_run'>282</p>
<p class='stm run hide_run'>283</p>
<p class='pln'>284</p>
<p class='pln'>285</p>
<p class='stm run hide_run'>286</p>
<p class='stm run hide_run'>287</p>
<p class='stm par run hide_run'>288</p>
<p class='stm mis'>289</p>
<p class='pln'>290</p>
<p class='stm run hide_run'>291</p>
<p class='pln'>292</p>
<p class='stm run hide_run'>293</p>
<p class='stm par run hide_run'>294</p>
<p class='stm mis'>295</p>
<p class='pln'>296</p>
<p class='stm par run hide_run'>297</p>
<p class='pln'>298</p>
<p class='stm run hide_run'>299</p>
<p class='stm run hide_run'>300</p>
<p class='stm run hide_run'>301</p>
<p class='stm par run hide_run'>302</p>
<p class='stm mis'>303</p>
<p class='pln'>304</p>
<p class='stm run hide_run'>305</p>
<p class='pln'>306</p>
<p class='stm par run hide_run'>307</p>
<p class='stm run hide_run'>308</p>
<p class='pln'>309</p>
<p class='stm run hide_run'>310</p>
<p class='stm run hide_run'>311</p>
<p class='stm mis'>312</p>
<p class='stm mis'>313</p>
<p class='pln'>314</p>
<p class='pln'>315</p>
<p class='stm run hide_run'>316</p>
<p class='stm run hide_run'>317</p>
<p class='stm run hide_run'>318</p>
<p class='stm par run hide_run'>319</p>
<p class='stm mis'>320</p>
<p class='stm run hide_run'>321</p>
<p class='stm mis'>322</p>
<p class='stm mis'>323</p>
<p class='stm mis'>324</p>
<p class='pln'>325</p>
<p class='stm mis'>326</p>
<p class='stm mis'>327</p>
<p class='stm mis'>328</p>
    
</td>
<td class='text' valign='top'>
<p class='pln'><span class='com'>#!/usr/bin/env python</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='com'># -*- coding: utf-8 -*-</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='str'>&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'> Modbus TestKit: Implementation of Modbus protocol in python</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'></span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'> (C)2009 - Luc Jean - luc.jean@gmail.com</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'> (C)2009 - Apidev - http://www.apidev.fr</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'></span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'> This is distributed under GNU LGPL license, see license.txt</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>from</span> <span class='nam'>modbus</span> <span class='key'>import</span> <span class='op'>*</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>import</span> <span class='nam'>socket</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>import</span> <span class='nam'>select</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>import</span> <span class='nam'>logging</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>from</span> <span class='nam'>hooks</span> <span class='key'>import</span> <span class='nam'>call_hooks</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>from</span> <span class='nam'>utils</span> <span class='key'>import</span> <span class='nam'>threadsafe_function</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>import</span> <span class='nam'>sys</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='com'>#-------------------------------------------------------------------------------</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>class</span> <span class='nam'>ModbusInvalidMbapError</span><span class='op'>(</span><span class='nam'>Exception</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Exception raised when the modbus TCP header doesn&#39;t correspond to what is expected&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>value</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>Exception</span><span class='op'>.</span><span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>value</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='com'>#-------------------------------------------------------------------------------</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='key'>class</span> <span class='nam'>TcpMbap</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Defines the information added by the Modbus TCP layer&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Constructor: initializes with 0&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>clone</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>mbap</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Set the value of each fields from another TcpMbap instance&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span> <span class='op'>=</span> <span class='nam'>mbap</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span> <span class='op'>=</span> <span class='nam'>mbap</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span> <span class='op'>=</span> <span class='nam'>mbap</span><span class='op'>.</span><span class='nam'>length</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span> <span class='op'>=</span> <span class='nam'>mbap</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_check_ids</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>request_mbap</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; Check that the ids in the request and the response are similar. </span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; if not returns a string describing the error</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>=</span> <span class='str'>&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>51</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>transaction_id</span> <span class='op'>!=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>+=</span> <span class='str'>&quot;Invalid transaction id: request=%d - response=%d. &quot;</span> <span class='op'>%</span><span class='op'>(</span><span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>protocol_id</span> <span class='op'>!=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>55</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>+=</span> <span class='str'>&quot;Invalid protocol id: request=%d - response=%d. &quot;</span> <span class='op'>%</span><span class='op'>(</span><span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>unit_id</span> <span class='op'>!=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>+=</span> <span class='str'>&quot;Invalid unit id: request=%d - response=%d. &quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>request_mbap</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>59</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>error_str</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>check_length</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>pdu_length</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Check the length field is valid. If not raise an exception&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>following_bytes_length</span> <span class='op'>=</span> <span class='nam'>pdu_length</span><span class='op'>+</span><span class='num'>1</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span> <span class='op'>!=</span> <span class='nam'>following_bytes_length</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='str'>&quot;Response length is %d while receiving %d bytes. &quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span><span class='op'>,</span> <span class='nam'>following_bytes_length</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>67</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='str'>&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>check_response</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>request_mbap</span><span class='op'>,</span> <span class='nam'>response_pdu_length</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Check that the MBAP of the response is valid. If not raise an exception&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_check_ids</span><span class='op'>(</span><span class='nam'>request_mbap</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>+=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>check_length</span><span class='op'>(</span><span class='nam'>response_pdu_length</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>error_str</span><span class='op'>)</span><span class='op'>&gt;</span><span class='num'>0</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>ModbusInvalidMbapError</span><span class='op'>,</span> <span class='nam'>error_str</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>75</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>pack</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;convert the TCP mbap into a string&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>struct</span><span class='op'>.</span><span class='nam'>pack</span><span class='op'>(</span><span class='str'>&quot;&gt;HHHB&quot;</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>unpack</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>value</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;extract the TCP mbap from a string&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>transaction_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>protocol_id</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>length</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>)</span> <span class='op'>=</span> <span class='nam'>struct</span><span class='op'>.</span><span class='nam'>unpack</span><span class='op'>(</span><span class='str'>&quot;&gt;HHHB&quot;</span><span class='op'>,</span> <span class='nam'>value</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='com'>#-------------------------------------------------------------------------------</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='key'>class</span> <span class='nam'>TcpQuery</span><span class='op'>(</span><span class='nam'>Query</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Subclass of a Query. Adds the Modbus TCP specific part of the protocol&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='com'>#static variable for giving a unique id to each query</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='nam'>_last_transaction_id</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Constructor&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>Query</span><span class='op'>.</span><span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span> <span class='op'>=</span> <span class='nam'>TcpMbap</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span> <span class='op'>=</span> <span class='nam'>TcpMbap</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='op'>@</span><span class='nam'>threadsafe_function</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_get_transaction_id</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;returns an identifier for the query&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>TcpQuery</span><span class='op'>.</span><span class='nam'>_last_transaction_id</span> <span class='op'>&lt;</span> <span class='num'>0xffff</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>TcpQuery</span><span class='op'>.</span><span class='nam'>_last_transaction_id</span> <span class='op'>+=</span> <span class='num'>1</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>104</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>TcpQuery</span><span class='op'>.</span><span class='nam'>_last_transaction_id</span> <span class='op'>=</span> <span class='num'>0</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>TcpQuery</span><span class='op'>.</span><span class='nam'>_last_transaction_id</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>build_request</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>pdu</span><span class='op'>,</span> <span class='nam'>slave</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Add the Modbus TCP part to the request&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='op'>(</span><span class='nam'>slave</span> <span class='op'>&lt;</span> <span class='num'>0</span><span class='op'>)</span> <span class='key'>or</span> <span class='op'>(</span><span class='nam'>slave</span> <span class='op'>&gt;=</span> <span class='num'>256</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>InvalidArgumentError</span><span class='op'>,</span> <span class='str'>&quot;%d Invalid value for slave id&quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>slave</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>110</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>length</span> <span class='op'>=</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>pdu</span><span class='op'>)</span><span class='op'>+</span><span class='num'>1</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>transaction_id</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_get_transaction_id</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>unit_id</span> <span class='op'>=</span> <span class='nam'>slave</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>mbap</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>pack</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>mbap</span><span class='op'>+</span><span class='nam'>pdu</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>parse_response</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>response</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Extract the pdu from the Modbus TCP response&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>response</span><span class='op'>)</span> <span class='op'>&gt;</span> <span class='num'>6</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>mbap</span><span class='op'>,</span> <span class='nam'>pdu</span> <span class='op'>=</span> <span class='nam'>response</span><span class='op'>[</span><span class='op'>:</span><span class='num'>7</span><span class='op'>]</span><span class='op'>,</span> <span class='nam'>response</span><span class='op'>[</span><span class='num'>7</span><span class='op'>:</span><span class='op'>]</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>125</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span><span class='op'>.</span><span class='nam'>unpack</span><span class='op'>(</span><span class='nam'>mbap</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span><span class='op'>.</span><span class='nam'>check_response</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>,</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>pdu</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>pdu</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>ModbusInvalidResponseError</span><span class='op'>,</span> <span class='str'>&quot;Response length is only %d bytes. &quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>len</span><span class='op'>(</span><span class='nam'>response</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>parse_request</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>request</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Extract the pdu from a modbus request&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span> <span class='op'>&gt;</span> <span class='num'>6</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>mbap</span><span class='op'>,</span> <span class='nam'>pdu</span> <span class='op'>=</span> <span class='nam'>request</span><span class='op'>[</span><span class='op'>:</span><span class='num'>7</span><span class='op'>]</span><span class='op'>,</span> <span class='nam'>request</span><span class='op'>[</span><span class='num'>7</span><span class='op'>:</span><span class='op'>]</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>137</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>unpack</span><span class='op'>(</span><span class='nam'>mbap</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>error_str</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>check_length</span><span class='op'>(</span><span class='nam'>len</span><span class='op'>(</span><span class='nam'>pdu</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>error_str</span><span class='op'>)</span> <span class='op'>&gt;</span> <span class='num'>0</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>ModbusInvalidMbapError</span><span class='op'>,</span> <span class='nam'>error_str</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>134</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>.</span><span class='nam'>unit_id</span><span class='op'>,</span> <span class='nam'>pdu</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>ModbusInvalidRequestError</span><span class='op'>,</span> <span class='str'>&quot;Request length is only %d bytes. &quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>len</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>build_response</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>response_pdu</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Build the response&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span><span class='op'>.</span><span class='nam'>clone</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_request_mbap</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span><span class='op'>.</span><span class='nam'>length</span> <span class='op'>=</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>response_pdu</span><span class='op'>)</span> <span class='op'>+</span> <span class='num'>1</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_response_mbap</span><span class='op'>.</span><span class='nam'>pack</span><span class='op'>(</span><span class='op'>)</span> <span class='op'>+</span> <span class='nam'>response_pdu</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='com'>#-------------------------------------------------------------------------------</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='key'>class</span> <span class='nam'>TcpMaster</span><span class='op'>(</span><span class='nam'>Master</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Subclass of Master. Implements the Modbus TCP MAC layer&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>host</span><span class='op'>=</span><span class='str'>&quot;127.0.0.1&quot;</span><span class='op'>,</span> <span class='nam'>port</span><span class='op'>=</span><span class='num'>502</span><span class='op'>,</span> <span class='nam'>timeout_in_sec</span><span class='op'>=</span><span class='num'>5.0</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Constructor. Set the communication settings&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>Master</span><span class='op'>.</span><span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>timeout_in_sec</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_host</span> <span class='op'>=</span> <span class='nam'>host</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_port</span> <span class='op'>=</span> <span class='nam'>port</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span> <span class='op'>=</span> <span class='nam'>None</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_do_open</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Connect to the Modbus slave&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span> <span class='op'>=</span> <span class='nam'>socket</span><span class='op'>.</span><span class='nam'>socket</span><span class='op'>(</span><span class='nam'>socket</span><span class='op'>.</span><span class='nam'>AF_INET</span><span class='op'>,</span> <span class='nam'>socket</span><span class='op'>.</span><span class='nam'>SOCK_STREAM</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>set_timeout</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>get_timeout</span><span class='op'>(</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.before_connect&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>connect</span><span class='op'>(</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_host</span><span class='op'>,</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_port</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.after_connect&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_do_close</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Close the connection with the Modbus Slave&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.before_close&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>exit</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>close</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.after_close&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>set_timeout</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>timeout_in_sec</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Change the timeout value&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>Master</span><span class='op'>.</span><span class='nam'>set_timeout</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>timeout_in_sec</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>setblocking</span><span class='op'>(</span><span class='nam'>timeout_in_sec</span><span class='op'>&gt;</span><span class='num'>0</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>timeout_in_sec</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>settimeout</span><span class='op'>(</span><span class='nam'>timeout_in_sec</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>exit</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_send</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>request</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Send request to the slave&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>retval</span> <span class='op'>=</span> <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.before_send&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>request</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>retval</span> <span class='op'>&lt;&gt;</span> <span class='nam'>None</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>request</span> <span class='op'>=</span> <span class='nam'>retval</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>183</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>utils</span><span class='op'>.</span><span class='nam'>flush_socket</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>send</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_recv</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>expected_length</span><span class='op'>=</span><span class='op'>-</span><span class='num'>1</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; Receive the response from the slave</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; Do not take expected_length into account because the length of the response is</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; written in the mbap. Used for RTU only</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='str'>&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>response</span> <span class='op'>=</span> <span class='str'>&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>length</span> <span class='op'>=</span> <span class='num'>255</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>while</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>response</span><span class='op'>)</span><span class='op'>&lt;</span><span class='nam'>length</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>rcv_byte</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>recv</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>rcv_byte</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>response</span> <span class='op'>+=</span> <span class='nam'>rcv_byte</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>204</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>response</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>6</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='op'>(</span><span class='nam'>tr_id</span><span class='op'>,</span> <span class='nam'>pr_id</span><span class='op'>,</span> <span class='nam'>to_be_recv_length</span><span class='op'>)</span> <span class='op'>=</span> <span class='nam'>struct</span><span class='op'>.</span><span class='nam'>unpack</span><span class='op'>(</span><span class='str'>&quot;&gt;HHH&quot;</span><span class='op'>,</span> <span class='nam'>response</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>length</span> <span class='op'>=</span> <span class='nam'>to_be_recv_length</span> <span class='op'>+</span> <span class='num'>6</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>break</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>retval</span> <span class='op'>=</span> <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpMaster.after_recv&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>response</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>retval</span> <span class='op'>&lt;&gt;</span> <span class='nam'>None</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>response</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>207</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>response</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_make_query</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Returns an instance of a Query subclass implementing the modbus TCP protocol&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>TcpQuery</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='com'>#-------------------------------------------------------------------------------</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='key'>class</span> <span class='nam'>TcpServer</span><span class='op'>(</span><span class='nam'>Server</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;This class implements a simple and mono-threaded modbus tcp server&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>port</span><span class='op'>=</span><span class='num'>502</span><span class='op'>,</span> <span class='nam'>address</span><span class='op'>=</span><span class='str'>&#39;localhost&#39;</span><span class='op'>,</span> <span class='nam'>timeout_in_sec</span><span class='op'>=</span><span class='num'>1</span><span class='op'>,</span> <span class='nam'>databank</span><span class='op'>=</span><span class='nam'>None</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Constructor: initializes the server settings&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>Server</span><span class='op'>.</span><span class='nam'>__init__</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>databank</span> <span class='key'>if</span> <span class='nam'>databank</span> <span class='key'>else</span> <span class='nam'>Databank</span><span class='op'>(</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span> <span class='op'>=</span> <span class='nam'>None</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sa</span> <span class='op'>=</span> <span class='op'>(</span><span class='nam'>address</span><span class='op'>,</span> <span class='nam'>port</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_timeout_in_sec</span> <span class='op'>=</span> <span class='nam'>timeout_in_sec</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span> <span class='op'>=</span> <span class='op'>[</span><span class='op'>]</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_make_query</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Returns an instance of a Query subclass implementing the modbus TCP protocol&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>TcpQuery</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_get_request_length</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>mbap</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;Parse the mbap and returns the number of bytes to be read&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>mbap</span><span class='op'>)</span> <span class='op'>&lt;</span> <span class='num'>6</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>raise</span> <span class='nam'>ModbusInvalidRequestError</span><span class='op'>(</span><span class='str'>&quot;The mbap is only %d bytes long&quot;</span><span class='op'>,</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>mbap</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>233</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='op'>(</span><span class='nam'>tr_id</span><span class='op'>,</span> <span class='nam'>pr_id</span><span class='op'>,</span> <span class='nam'>length</span><span class='op'>)</span> <span class='op'>=</span> <span class='nam'>struct</span><span class='op'>.</span><span class='nam'>unpack</span><span class='op'>(</span><span class='str'>&quot;&gt;HHH&quot;</span><span class='op'>,</span> <span class='nam'>mbap</span><span class='op'>[</span><span class='op'>:</span><span class='num'>6</span><span class='op'>]</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>return</span> <span class='nam'>length</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_do_init</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;initialize server&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span> <span class='op'>=</span> <span class='nam'>socket</span><span class='op'>.</span><span class='nam'>socket</span><span class='op'>(</span><span class='nam'>socket</span><span class='op'>.</span><span class='nam'>AF_INET</span><span class='op'>,</span> <span class='nam'>socket</span><span class='op'>.</span><span class='nam'>SOCK_STREAM</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_timeout_in_sec</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>settimeout</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_timeout_in_sec</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>242</span>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>setblocking</span><span class='op'>(</span><span class='num'>0</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>bind</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sa</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>listen</span><span class='op'>(</span><span class='num'>10</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>.</span><span class='nam'>append</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_do_exit</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;clean the server tasks&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#close the sockets</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>for</span> <span class='nam'>sock</span> <span class='key'>in</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>try</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>close</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>.</span><span class='nam'>remove</span><span class='op'>(</span><span class='nam'>sock</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>except</span> <span class='nam'>Exception</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>warning</span><span class='op'>(</span><span class='str'>&quot;Error while closing socket, Exception occurred: %s&quot;</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; <span class='key'>def</span> <span class='nam'>_do_run</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>)</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='str'>&quot;&quot;&quot;called in a almost-for-ever loop by the server&quot;&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#check the status of every socket</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>inputready</span><span class='op'>,</span> <span class='nam'>outputready</span><span class='op'>,</span> <span class='nam'>exceptready</span> <span class='op'>=</span> <span class='nam'>select</span><span class='op'>.</span><span class='nam'>select</span><span class='op'>(</span><span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>,</span> <span class='op'>[</span><span class='op'>]</span><span class='op'>,</span> <span class='op'>[</span><span class='op'>]</span><span class='op'>,</span> <span class='num'>1.0</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>for</span> <span class='nam'>sock</span> <span class='key'>in</span> <span class='nam'>inputready</span><span class='op'>:</span> <span class='com'>#handle data on each a socket</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>try</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>sock</span> <span class='op'>==</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'># handle the server socket</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>client</span><span class='op'>,</span> <span class='nam'>address</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sock</span><span class='op'>.</span><span class='nam'>accept</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>client</span><span class='op'>.</span><span class='nam'>setblocking</span><span class='op'>(</span><span class='num'>0</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>info</span><span class='op'>(</span><span class='str'>&quot;%s is connected with socket %d...&quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>str</span><span class='op'>(</span><span class='nam'>address</span><span class='op'>)</span><span class='op'>,</span> <span class='nam'>client</span><span class='op'>.</span><span class='nam'>fileno</span><span class='op'>(</span><span class='op'>)</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>.</span><span class='nam'>append</span><span class='op'>(</span><span class='nam'>client</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpServer.on_connect&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>client</span><span class='op'>,</span> <span class='nam'>address</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>sock</span><span class='op'>.</span><span class='nam'>recv</span><span class='op'>(</span><span class='num'>1</span><span class='op'>,</span> <span class='nam'>socket</span><span class='op'>.</span><span class='nam'>MSG_PEEK</span><span class='op'>)</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>0</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#socket is disconnected</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>info</span><span class='op'>(</span><span class='str'>&quot;%d is disconnected&quot;</span> <span class='op'>%</span> <span class='op'>(</span><span class='nam'>sock</span><span class='op'>.</span><span class='nam'>fileno</span><span class='op'>(</span><span class='op'>)</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpServer.on_disconnect&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>sock</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>close</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>.</span><span class='nam'>remove</span><span class='op'>(</span><span class='nam'>sock</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>break</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'># handle all other sockets</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>settimeout</span><span class='op'>(</span><span class='num'>1.0</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>request</span> <span class='op'>=</span> <span class='str'>&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>is_ok</span> <span class='op'>=</span> <span class='nam'>True</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#read the 7 bytes of the mbap</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>while</span> <span class='op'>(</span><span class='nam'>len</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span> <span class='op'>&lt;</span> <span class='num'>7</span><span class='op'>)</span> <span class='key'>and</span> <span class='nam'>is_ok</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>new_byte</span> <span class='op'>=</span> <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>recv</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>new_byte</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>0</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>is_ok</span> <span class='op'>=</span> <span class='nam'>False</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>289</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>request</span> <span class='op'>+=</span> <span class='nam'>new_byte</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>retval</span> <span class='op'>=</span> <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpServer.after_recv&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>sock</span><span class='op'>,</span> <span class='nam'>request</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>retval</span> <span class='op'>&lt;&gt;</span> <span class='nam'>None</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>request</span> <span class='op'>=</span> <span class='nam'>retval</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>295</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>is_ok</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#read the rest of the request</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>307</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>length</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_get_request_length</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>while</span> <span class='op'>(</span><span class='nam'>len</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span> <span class='op'>&lt;</span> <span class='op'>(</span><span class='nam'>length</span> <span class='op'>+</span> <span class='num'>6</span><span class='op'>)</span><span class='op'>)</span> <span class='key'>and</span> <span class='nam'>is_ok</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>new_byte</span> <span class='op'>=</span> <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>recv</span><span class='op'>(</span><span class='num'>1</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>len</span><span class='op'>(</span><span class='nam'>new_byte</span><span class='op'>)</span> <span class='op'>==</span> <span class='num'>0</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>is_ok</span> <span class='op'>=</span> <span class='nam'>False</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>303</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>else</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>request</span> <span class='op'>+=</span> <span class='nam'>new_byte</span><span class='strut'>&nbsp;</span></p>
<p class='pln'><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>is_ok</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>response</span> <span class='op'>=</span> <span class='str'>&quot;&quot;</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>262</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#parse the request</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>try</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>response</span> <span class='op'>=</span> <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_handle</span><span class='op'>(</span><span class='nam'>request</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>except</span> <span class='nam'>Exception</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>error</span><span class='op'>(</span><span class='str'>&quot;Error while handling a request, Exception occurred: %s&quot;</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='com'>#send back the response</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>response</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>try</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>retval</span> <span class='op'>=</span> <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpServer.before_send&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>sock</span><span class='op'>,</span> <span class='nam'>response</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>if</span> <span class='nam'>retval</span> <span class='op'>&lt;&gt;</span> <span class='nam'>None</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>response</span> <span class='op'>=</span> <span class='nam'>retval</span><span class='strut'>&nbsp;</span></p>
<p class='stm par run hide_run'><span class='annotate' title='no jump to this line number'>320</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>send</span><span class='op'>(</span><span class='nam'>response</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>except</span> <span class='nam'>Exception</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm run hide_run'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>is_ok</span> <span class='op'>=</span> <span class='nam'>False</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>error</span><span class='op'>(</span><span class='str'>&quot;Error while sending on socket %d, Exception occurred: %s&quot;</span><span class='op'>,</span><span class='nam'>sock</span><span class='op'>.</span><span class='nam'>fileno</span><span class='op'>(</span><span class='op'>)</span><span class='op'>,</span> <span class='nam'>msg</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='key'>except</span> <span class='nam'>Exception</span><span class='op'>,</span> <span class='nam'>excpt</span><span class='op'>:</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>LOGGER</span><span class='op'>.</span><span class='nam'>warning</span><span class='op'>(</span><span class='str'>&quot;Error while processing data on socket %d: %s&quot;</span><span class='op'>,</span> <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>fileno</span><span class='op'>(</span><span class='op'>)</span><span class='op'>,</span> <span class='nam'>excpt</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='pln'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>call_hooks</span><span class='op'>(</span><span class='str'>&quot;modbus_tcp.TcpServer.on_error&quot;</span><span class='op'>,</span> <span class='op'>(</span><span class='nam'>self</span><span class='op'>,</span> <span class='nam'>sock</span><span class='op'>,</span> <span class='nam'>excpt</span><span class='op'>)</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>sock</span><span class='op'>.</span><span class='nam'>close</span><span class='op'>(</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class='nam'>self</span><span class='op'>.</span><span class='nam'>_sockets</span><span class='op'>.</span><span class='nam'>remove</span><span class='op'>(</span><span class='nam'>sock</span><span class='op'>)</span><span class='strut'>&nbsp;</span></p>
<p class='stm mis'><span class='strut'>&nbsp;</span></p>
    
</td>
</tr>
</table>
</div>

</body>
</html>
